/**
 * 树莓派无电阻智能门禁系统 - 完整代码
 * 功能：按键密码验证 + RGB状态指示 + 蜂鸣器音乐反馈
 * 硬件：按键模块、共阴RGB LED、无源蜂鸣器（无电阻方案）
 * 依赖：WiringPi库
 */

 #include <wiringPi.h>
 #include <softPwm.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
 
 // === 硬件引脚定义（WiringPi编号） ===
 #define BUTTON_PIN   4   // 按键 -> GPIO23
 #define RGB_R        0   // R通道 -> GPIO17
 #define RGB_G        1   // G通道 -> GPIO18
 #define RGB_B        2   // B通道 -> GPIO27
 #define BUZZER_PIN   5   // 蜂鸣器 -> GPIO24
 
 // === 系统参数配置 ===
 #define PASSWORD         3       // 正确密码按键次数
 #define MAX_BRIGHT       30      // PWM最大亮度（30%占空比）
 #define DEBOUNCE_MS      20      // 按键消抖时间
 #define INPUT_TIMEOUT    5000    // 输入超时（毫秒）
 
 // === 音乐频率定义（单位：Hz） ===
 #define C4  262
 #define D4  294
 #define E4  330
 #define F4  349
 #define G4  392
 #define A4  440
 #define B4  494
 
 // === 全局变量 ===
 int pressCount = 0;              // 按键计数
 unsigned long lastPressTime = 0; // 最后按键时间
 
 // === 函数声明 ===
 void setRGB(int r, int g, int b);
 void buzzerTone(int freq, int duration);
 void playSuccessMusic();
 void playErrorMusic();
 void breathingEffect();
 int checkButton();
 
 /******************************
  * 安全RGB控制（核心函数）
  ******************************/
 void setRGB(int r, int g, int b) {
     // 硬件保护：限制最大亮度
     r = (r > MAX_BRIGHT) ? MAX_BRIGHT : r;
     g = (g > MAX_BRIGHT) ? MAX_BRIGHT : g;
     b = (b > MAX_BRIGHT) ? MAX_BRIGHT : b;
     
     softPwmWrite(RGB_R, r);
     softPwmWrite(RGB_G, g);
     softPwmWrite(RGB_B, b);
 }
 
 /******************************
  * 蜂鸣器控制（精确时序）
  ******************************/
 void buzzerTone(int freq, int duration) {
     if(freq <= 0) {
         digitalWrite(BUZZER_PIN, LOW);
         delay(duration);
         return;
     }
     
     int periodUs = 1000000 / freq;  // 周期（微秒）
     int cycles = duration * 1000 / periodUs;
     
     for(int i=0; i<cycles; i++) {
         digitalWrite(BUZZER_PIN, HIGH);
         delayMicroseconds(periodUs / 2);
         digitalWrite(BUZZER_PIN, LOW);
         delayMicroseconds(periodUs / 2);
     }
 }
 
 /******************************
  * 成功音乐（《小星星》片段）
  ******************************/
 void playSuccessMusic() {
     int melody[] = {C4, C4, G4, G4, A4, A4, G4, F4, F4, E4, E4, D4, D4, C4};
     int rhythm[] = {200, 200, 200, 200, 200, 200, 400, 200, 200, 200, 200, 200, 200, 400};
     
     for(int i=0; i<14; i++) {
         buzzerTone(melody[i], rhythm[i]);
     }
 }
 
 /******************************
  * 错误音乐（警报声）
  ******************************/
 void playErrorMusic() {
     for(int i=0; i<4; i++) {
         buzzerTone(C4, 200);
         buzzerTone(0, 200);  // 间隔
     }
 }
 
 /******************************
  * 呼吸灯效果（待机状态）
  ******************************/
 void breathingEffect() {
     static int breath = 0;
     static int dir = 1;
     
     breath += dir;
     if(breath > 15 || breath < 0) dir *= -1;
     setRGB(0, 0, breath);  // 蓝色呼吸
 }
 
 /******************************
  * 按键检测（带消抖和超时）
  ******************************/
 int checkButton() {
     static unsigned long lastTime = 0;
     unsigned long now = millis();
     
     if(digitalRead(BUTTON_PIN) == LOW) {
         if(now - lastTime > DEBOUNCE_MS) {
             lastTime = now;
             return 1;  // 有效按键
         }
     }
     return 0;
 }
 
 /******************************
  * 系统初始化
  ******************************/
 void initSystem() {
     if(wiringPiSetup() == -1) {
         fprintf(stderr, "WiringPi初始化失败！\n");
         exit(1);
     }
     
     // 初始化RGB PWM
     softPwmCreate(RGB_R, 0, 100);
     softPwmCreate(RGB_G, 0, 100);
     softPwmCreate(RGB_B, 0, 100);
     
     // 初始化按键（启用内部上拉）
     pinMode(BUTTON_PIN, INPUT);
     pullUpDnControl(BUTTON_PIN, PUD_UP);
     
     // 初始化蜂鸣器
     pinMode(BUZZER_PIN, OUTPUT);
     
     printf("=== 系统启动 ===\n");
 }
 
 /******************************
  * 主程序
  ******************************/
 int main() {
     initSystem();
     setRGB(0, 0, 5);  // 初始低亮蓝光
     
     while(1) {
         // 1. 检测按键输入
         if(checkButton()) {
             pressCount++;
             lastPressTime = millis();
             printf("按键次数: %d\n", pressCount);
             
             // 输入反馈：白光闪烁
             setRGB(MAX_BRIGHT, MAX_BRIGHT, MAX_BRIGHT);
             buzzerTone(G4, 100);
             delay(100);
         }
         
         // 2. 输入超时检测
         if((millis() - lastPressTime) > INPUT_TIMEOUT && pressCount > 0) {
             pressCount = 0;
             printf("输入超时，已重置！\n");
         }
         
         // 3. 密码验证
         if(pressCount >= PASSWORD) {
             if(pressCount == PASSWORD) {  // 正确
                 setRGB(0, MAX_BRIGHT, 0); // 绿灯
                 playSuccessMusic();
                 delay(3000);
             } else {                      // 错误
                 setRGB(MAX_BRIGHT, 0, 0); // 红灯
                 playErrorMusic();
                 delay(2000);
             }
             pressCount = 0;
             setRGB(0, 0, 5);  // 恢复待机
         }
         
         // 4. 待机呼吸效果
         breathingEffect();
         delay(50);
     }
     
     return 0;
 }